﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Threading;

namespace Nine.SocketLibrary
{
    public class SocketClient
    {
        public SocketClient()
        {
            Init();
        }
        public LinkRelated ClientListModel = new LinkRelated();
        public List<LinkRelated> ClientList = new List<LinkRelated>();
        string MsgText = "";
        //创建1个客户端套接字和1个负责监听服务端请求的线程  
        static Thread ThreadClient = null;
        public static Socket socketClient = null;
        private void Init()
        {
            try
            {
                int port = Convert.ToInt32(ConfigurationManager.AppSettings["Port"]);

                string host = ConfigurationManager.AppSettings["ServiceIp"];
                IPAddress ip = IPAddress.Parse(host);
                IPEndPoint ipe = new IPEndPoint(ip, port);

                //定义一个套接字监听  
                socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                try
                {
                    //客户端套接字连接到网络节点上，用的是Connect  
                    socketClient.Connect(ipe);
                }
                catch (Exception)
                {
                    return;
                }

                ThreadClient = new Thread(Recv)
                {
                    IsBackground = true
                };
                ThreadClient.Start();

                Thread.Sleep(1000);
            }
            catch (Exception)
            {
                return;
            }
        }
        //发送字符信息到服务端的方法  
        public static void ClientSendMsg(string sendMsg)
        {
            //将输入的内容字符串转换为机器可以识别的字节数组     
            byte[] arrClientSendMsg = Encoding.UTF8.GetBytes(sendMsg);
            //调用客户端套接字发送字节数组     
            socketClient.Send(arrClientSendMsg);
        }

        //接收服务端发来信息的方法    
        public void Recv()
        {
            //持续监听服务端发来的消息 
            while (true)
            {
                try
                {
                    //定义一个1M的内存缓冲区，用于临时性存储接收到的消息  
                    byte[] arrRecvmsg = new byte[1024 * 1024];

                    //将客户端套接字接收到的数据存入内存缓冲区，并获取长度  
                    int length = socketClient.Receive(arrRecvmsg);

                    //将套接字获取到的字符数组转换为人可以看懂的字符串  

                    string strRevMsg = Encoding.UTF8.GetString(arrRecvmsg, 0, length);


                    bool login = false;
                    string[] Logstr = strRevMsg.Split('@');
                    if (Logstr[0].Contains("Login"))
                    {
                        login = true;
                    }
                    ThreadPool.QueueUserWorkItem(delegate
                    {
                        SynchronizationContext.SetSynchronizationContext(new
                        DispatcherSynchronizationContext(System.Windows.Application.Current.Dispatcher));
                        SynchronizationContext.Current.Post(pl =>
                        {
                            //解决异步线程调用回归主线程
                            //System.NotSupportedException:“该类型的 CollectionView 不支持从调度程序线程以外的线程对其 SourceCollection 进行的更改。”
                            if (login)
                            {
                                for (int i = 1; i < Logstr.Count() - 1; i++)
                                {

                                    ClientListModel = new LinkRelated
                                    {
                                        ContentText = Logstr[i]
                                    };

                                    ClientList.Add(ClientListModel);
                                    ClientList = new List<LinkRelated>(ClientList.Distinct(t => t.ContentText).ToList());
                                }
                            }
                            else
                            {
                                MsgText += strRevMsg + "\r\n\r\n";
                            }
                        }, null);
                    });
                }
                catch (Exception)
                {
                    break;
                }
            }
        }
    }
}
